<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  

   <!-- 百度联盟 -->
   <meta name="baidu_union_verify" content="46e227ad81d5513c6cd8288c18c6ebad">

   <!-- google analytics -->
   <meta name="google-site-verification" content="SzCGQVmA8Mtk40elee-bCGpq2YSCAmEulSNEZHYCkFc" />

   <!--百度站长之家验证-->
   <meta name="baidu-site-verification" content="4woRik4rfk" />

   <meta name="description" content="坑要一个个填，路要一步步走！—— from zhisheng的博客">
   <meta name="keywords" content="Java,架构,后端,服务端,RocketMQ,分布式消息队列,分布式存储,技术博客,HBase,ElasticSearch,Spring,Spring Boot,Spring Boot 2.0,Spring Cloud,Spring MVC,Java EE,前端,HTML,MyBatis,Android,Docker,Mac,Consul,Kafka,Logstash,Kibana,MySQL,Maven,Nginx,Python,RabbitMQ,ActiveMQ,JVM">


  <title>通过项目逐步深入了解Mybatis（二） | zhisheng的博客</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="转载请务必注明出处，原创不易！  相关文章：通过项目逐步深入了解Mybatis&amp;lt;一&amp;gt;本项目全部代码地址：Github-Mybatis Mybatis 解决 jdbc 编程的问题1、  数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能，如果使用数据库链接池可解决此问题。 解决：在SqlMapConfig.xml中配置数据链接池，使用连接池管理数据库链接。 2、  Sql语句写在代">
<meta name="keywords" content="Mybatis,SpringMVC">
<meta property="og:type" content="article">
<meta property="og:title" content="通过项目逐步深入了解Mybatis（二）">
<meta property="og:url" content="http://www.54tianzhisheng.cn/2017/06/13/通过项目逐步深入了解Mybatis(二)/index.html">
<meta property="og:site_name" content="zhisheng的博客">
<meta property="og:description" content="转载请务必注明出处，原创不易！  相关文章：通过项目逐步深入了解Mybatis&amp;lt;一&amp;gt;本项目全部代码地址：Github-Mybatis Mybatis 解决 jdbc 编程的问题1、  数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能，如果使用数据库链接池可解决此问题。 解决：在SqlMapConfig.xml中配置数据链接池，使用连接池管理数据库链接。 2、  Sql语句写在代">
<meta property="og:locale" content="zh-Hans">
<meta property="og:image" content="http://image.54tianzhisheng.cn/dao%E5%BC%80%E5%8F%91.jpg">
<meta property="og:image" content="http://image.54tianzhisheng.cn/mapper%E5%BC%80%E5%8F%91.jpg">
<meta property="og:image" content="http://image.54tianzhisheng.cn/mapper%E5%BC%80%E5%8F%912.jpg">
<meta property="og:image" content="http://image.54tianzhisheng.cn/%E6%8A%A5%E9%94%99.jpg">
<meta property="og:image" content="http://image.54tianzhisheng.cn/setting.jpg">
<meta property="og:image" content="http://image.54tianzhisheng.cn/Test4.jpg">
<meta property="og:image" content="http://image.54tianzhisheng.cn/Test5.jpg">
<meta property="og:image" content="http://image.54tianzhisheng.cn/Test6.jpg">
<meta property="og:image" content="http://image.54tianzhisheng.cn/Test7.jpg">
<meta property="og:image" content="http://image.54tianzhisheng.cn/Test8.jpg">
<meta property="og:image" content="https://ws3.sinaimg.cn/large/006tNc79gy1fp3jkmizmpj30o00didgn.jpg">
<meta property="og:updated_time" content="2018-11-22T14:51:58.000Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="通过项目逐步深入了解Mybatis（二）">
<meta name="twitter:description" content="转载请务必注明出处，原创不易！  相关文章：通过项目逐步深入了解Mybatis&amp;lt;一&amp;gt;本项目全部代码地址：Github-Mybatis Mybatis 解决 jdbc 编程的问题1、  数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能，如果使用数据库链接池可解决此问题。 解决：在SqlMapConfig.xml中配置数据链接池，使用连接池管理数据库链接。 2、  Sql语句写在代">
<meta name="twitter:image" content="http://image.54tianzhisheng.cn/dao%E5%BC%80%E5%8F%91.jpg">
  
    <link rel="alternative" href="/atom.xml" title="zhisheng的博客" type="application/atom+xml">
  
  
    <link rel="icon" href="/img/favicon.ico">
  
  
      <link rel="stylesheet" href="//cdn.bootcss.com/animate.css/3.5.0/animate.min.css">
  
  <link rel="stylesheet" href="/css/style.css">
  <link rel="stylesheet" href="/font-awesome/css/font-awesome.min.css">
  <link rel="apple-touch-icon" href="/apple-touch-icon.png">
  
  
      <link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
  
  <!-- 加载特效 -->
  <script src="/js/pace.js"></script>
  <link href="/css/pace/pace-theme-flash.css" rel="stylesheet" />
  <script>
      var yiliaConfig = {
          rootUrl: '/',
          fancybox: true,
          animate: true,
          isHome: false,
          isPost: true,
          isArchive: false,
          isTag: false,
          isCategory: false,
          open_in_new: true
      }
  </script>
</head>
<body>
  <div id="container">
    <div class="left-col">
    <div class="overlay"></div>
<div class="intrude-less">
    <header id="header" class="inner">
        <a href="/" class="profilepic">
            
            <img lazy-src="/img/avatar.png" class="js-avatar">
            
        </a>

        <hgroup>
          <h1 class="header-author"><a href="/">zhisheng</a></h1>
        </hgroup>

        
        <p class="header-subtitle">坑要一个个填，路要一步步走！</p>
        
        
        
            <div id="switch-btn" class="switch-btn">
                <div class="icon">
                    <div class="icon-ctn">
                        <div class="icon-wrap icon-house" data-idx="0">
                            <div class="birdhouse"></div>
                            <div class="birdhouse_holes"></div>
                        </div>
                        <div class="icon-wrap icon-ribbon hide" data-idx="1">
                            <div class="ribbon"></div>
                        </div>
                        
                        <div class="icon-wrap icon-link hide" data-idx="2">
                            <div class="loopback_l"></div>
                            <div class="loopback_r"></div>
                        </div>
                        
                        
                        <div class="icon-wrap icon-me hide" data-idx="3">
                            <div class="user"></div>
                            <div class="shoulder"></div>
                        </div>
                        
                    </div>
                    
                </div>
                <div class="tips-box hide">
                    <div class="tips-arrow"></div>
                    <ul class="tips-inner">
                        <li>菜单</li>
                        <li>标签</li>
                        
                        <li>友情链接</li>
                        
                        
                        <li>关于我</li>
                        
                    </ul>
                </div>
            </div>
        

        <div id="switch-area" class="switch-area">
            <div class="switch-wrap">
                <section class="switch-part switch-part1">
                    <nav class="header-menu">
                        <ul>
                        
                            <li><a href="/">主页</a></li>
                        
                            <li><a href="/tags/Flink/">Flink</a></li>
                        
                            <li><a href="/tags/ElasticSearch/">ElasticSearch</a></li>
                        
                            <li><a href="/tags/SpringBoot/">Spring Boot</a></li>
                        
                        </ul>
                    </nav>
                    <nav class="header-nav">
                        <ul class="social">
                            
                                <a class="fl wechat" target="_blank" href="wechat:zhisheng_tian" title="wechat">wechat</a>
                            
                                <a class="fl mail" target="_blank" href="mailto://zhisheng2018@gmail.com" title="mail">mail</a>
                            
                                <a class="fl github" target="_blank" href="https://github.com/zhisheng17/" title="github">github</a>
                            
                                <a class="fl zhihu" target="_blank" href="https://www.zhihu.com/people/tian-zhisheng/activities" title="zhihu">zhihu</a>
                            
                        </ul>
                    </nav>
                </section>
                
                
                <section class="switch-part switch-part2">
                    <div class="widget tagcloud" id="js-tagcloud">
                        <a href="/tags/AJAX/" style="font-size: 10px;">AJAX</a> <a href="/tags/ActiveMQ/" style="font-size: 10px;">ActiveMQ</a> <a href="/tags/Android/" style="font-size: 10px;">Android</a> <a href="/tags/Bootstrap/" style="font-size: 13px;">Bootstrap</a> <a href="/tags/Consul/" style="font-size: 10px;">Consul</a> <a href="/tags/Docker/" style="font-size: 11px;">Docker</a> <a href="/tags/ElasticSearch/" style="font-size: 17px;">ElasticSearch</a> <a href="/tags/Filter过滤器/" style="font-size: 10px;">Filter过滤器</a> <a href="/tags/Flink/" style="font-size: 18px;">Flink</a> <a href="/tags/GO/" style="font-size: 10px;">GO</a> <a href="/tags/Github-Page/" style="font-size: 10px;">Github Page</a> <a href="/tags/Guava/" style="font-size: 10px;">Guava</a> <a href="/tags/HBase/" style="font-size: 10px;">HBase</a> <a href="/tags/Hibernate-JPA/" style="font-size: 11px;">Hibernate JPA</a> <a href="/tags/IO/" style="font-size: 11px;">IO</a> <a href="/tags/JMM/" style="font-size: 10px;">JMM</a> <a href="/tags/JSON/" style="font-size: 10px;">JSON</a> <a href="/tags/JVM/" style="font-size: 11px;">JVM</a> <a href="/tags/Java/" style="font-size: 20px;">Java</a> <a href="/tags/Kafka/" style="font-size: 12px;">Kafka</a> <a href="/tags/Kibana/" style="font-size: 10px;">Kibana</a> <a href="/tags/LogStash/" style="font-size: 10px;">LogStash</a> <a href="/tags/Mac/" style="font-size: 10px;">Mac</a> <a href="/tags/Maven/" style="font-size: 11px;">Maven</a> <a href="/tags/MySQL/" style="font-size: 12px;">MySQL</a> <a href="/tags/Mybatis/" style="font-size: 14px;">Mybatis</a> <a href="/tags/NIO/" style="font-size: 10px;">NIO</a> <a href="/tags/Netty/" style="font-size: 10px;">Netty</a> <a href="/tags/Nginx/" style="font-size: 11px;">Nginx</a> <a href="/tags/Oracle/" style="font-size: 10px;">Oracle</a> <a href="/tags/Pyspider/" style="font-size: 10px;">Pyspider</a> <a href="/tags/Python/" style="font-size: 12px;">Python</a> <a href="/tags/RabbitMQ/" style="font-size: 11px;">RabbitMQ</a> <a href="/tags/Redis/" style="font-size: 11px;">Redis</a> <a href="/tags/RocketMQ/" style="font-size: 13px;">RocketMQ</a> <a href="/tags/Servlet/" style="font-size: 10px;">Servlet</a> <a href="/tags/Spring/" style="font-size: 12px;">Spring</a> <a href="/tags/Spring-MVC/" style="font-size: 15px;">Spring MVC</a> <a href="/tags/SpringBoot/" style="font-size: 19px;">SpringBoot</a> <a href="/tags/SpringCloud/" style="font-size: 10px;">SpringCloud</a> <a href="/tags/SpringMVC/" style="font-size: 13px;">SpringMVC</a> <a href="/tags/String/" style="font-size: 10px;">String</a> <a href="/tags/Velocity/" style="font-size: 10px;">Velocity</a> <a href="/tags/Zookeeper/" style="font-size: 10px;">Zookeeper</a> <a href="/tags/finally/" style="font-size: 10px;">finally</a> <a href="/tags/foreach/" style="font-size: 10px;">foreach</a> <a href="/tags/hexo/" style="font-size: 12px;">hexo</a> <a href="/tags/lombok/" style="font-size: 10px;">lombok</a> <a href="/tags/lua/" style="font-size: 10px;">lua</a> <a href="/tags/yilia/" style="font-size: 11px;">yilia</a> <a href="/tags/书籍/" style="font-size: 10px;">书籍</a> <a href="/tags/分布式锁/" style="font-size: 10px;">分布式锁</a> <a href="/tags/前端/" style="font-size: 12px;">前端</a> <a href="/tags/励志/" style="font-size: 10px;">励志</a> <a href="/tags/博客合集/" style="font-size: 10px;">博客合集</a> <a href="/tags/博客网站/" style="font-size: 10px;">博客网站</a> <a href="/tags/多线程/" style="font-size: 11px;">多线程</a> <a href="/tags/大数据/" style="font-size: 18px;">大数据</a> <a href="/tags/字符串/" style="font-size: 11px;">字符串</a> <a href="/tags/实习圈/" style="font-size: 10px;">实习圈</a> <a href="/tags/循环队列/" style="font-size: 10px;">循环队列</a> <a href="/tags/微服务/" style="font-size: 11px;">微服务</a> <a href="/tags/性能调优工具/" style="font-size: 10px;">性能调优工具</a> <a href="/tags/投资理财/" style="font-size: 10px;">投资理财</a> <a href="/tags/数据库/" style="font-size: 12px;">数据库</a> <a href="/tags/数据结构/" style="font-size: 13px;">数据结构</a> <a href="/tags/文件/" style="font-size: 10px;">文件</a> <a href="/tags/旋转词/" style="font-size: 10px;">旋转词</a> <a href="/tags/流式计算/" style="font-size: 18px;">流式计算</a> <a href="/tags/流控/" style="font-size: 10px;">流控</a> <a href="/tags/爬虫/" style="font-size: 12px;">爬虫</a> <a href="/tags/算法/" style="font-size: 12px;">算法</a> <a href="/tags/类加载机制/" style="font-size: 10px;">类加载机制</a> <a href="/tags/线程池/" style="font-size: 10px;">线程池</a> <a href="/tags/编码/" style="font-size: 10px;">编码</a> <a href="/tags/表达式/" style="font-size: 10px;">表达式</a> <a href="/tags/邮件发送/" style="font-size: 10px;">邮件发送</a> <a href="/tags/随笔/" style="font-size: 16px;">随笔</a> <a href="/tags/面经/" style="font-size: 16px;">面经</a>
                    </div>
                </section>
                
                
                
                <section class="switch-part switch-part3">
                    <div id="js-friends">
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://blog.csdn.net/tzs_1041218129">CSDN博客</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="https://juejin.im/user/57510b82128fe10056ca70fc">掘金</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://www.iocoder.cn/?vip">芋道源码</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://fengzhaofeng.net/">冯兆峯</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://www.codedata.cn/">CodeData</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="https://investguider.com/">美股指南</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://www.songyawei.cn/">Linux运维工程师</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://www.carlzone.cn/">carl.zhao</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://dongkelun.com/">伦少的博客</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://www.jiangxinlingdu.com/">匠心零度</a>
                    
                    </div>
                </section>
                

                
                
                <section class="switch-part switch-part4">
                
                    <div id="js-aboutme">17.08 ~ 18.05 永辉云创基础架构组实习     2018.06 大学毕业   2018.06 ～ 现在  另一家公司各种折腾!</div>
                </section>
                
            </div>
        </div>
        <div>
            <img src="/img/wx.jpg"  alt="zhisheng" />
        </div>
    </header>
</div>
    </div>
    <div class="mid-col">
      <nav id="mobile-nav">
      <div class="overlay">
          <div class="slider-trigger"></div>
          <h1 class="header-author js-mobile-header hide"><a href="/" title="Me">zhisheng</a></h1>
      </div>
    <div class="intrude-less">
        <header id="header" class="inner">
            <a href="/" class="profilepic">
                
                    <img lazy-src="/img/avatar.png" class="js-avatar">
                
            </a>
            <hgroup>
              <h1 class="header-author"><a href="/" title="Me">zhisheng</a></h1>
            </hgroup>
            
            <p class="header-subtitle">坑要一个个填，路要一步步走！</p>
            
            <nav class="header-menu">
                <ul>
                
                    <li><a href="/">主页</a></li>
                
                    <li><a href="/tags/Flink/">Flink</a></li>
                
                    <li><a href="/tags/ElasticSearch/">ElasticSearch</a></li>
                
                    <li><a href="/tags/SpringBoot/">Spring Boot</a></li>
                
                <div class="clearfix"></div>
                </ul>
            </nav>
            <nav class="header-nav">
                <div class="social">
                    
                        <a class="wechat" target="_blank" href="wechat:zhisheng_tian" title="wechat">wechat</a>
                    
                        <a class="mail" target="_blank" href="mailto://zhisheng2018@gmail.com" title="mail">mail</a>
                    
                        <a class="github" target="_blank" href="https://github.com/zhisheng17/" title="github">github</a>
                    
                        <a class="zhihu" target="_blank" href="https://www.zhihu.com/people/tian-zhisheng/activities" title="zhihu">zhihu</a>
                    
                </div>
            </nav>
        </header>                
    </div>
</nav>
      <div class="body-wrap"><article id="post-通过项目逐步深入了解Mybatis(二)" class="article article-type-post" itemscope itemprop="blogPost">
  
    <div class="article-meta">
      <a href="/2017/06/13/通过项目逐步深入了解Mybatis(二)/" class="article-date">
      <time datetime="2017-06-12T16:00:00.000Z" itemprop="datePublished">2017-06-13</time>
</a>
    </div>
  
  <div class="article-inner">
    
      <input type="hidden" class="isFancy" />
    
    
      <header class="article-header">
        
  
    <h1 class="article-title" itemprop="name">
      通过项目逐步深入了解Mybatis（二）
    </h1>
  

      </header>
      
      <div class="article-info article-info-post">
        

        
    <div class="article-tag tagcloud">
        <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Mybatis/">Mybatis</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/SpringMVC/">SpringMVC</a></li></ul>
    </div>

        <div class="clearfix"></div>
      </div>
      
    
    <div class="article-entry" itemprop="articleBody">
      
          
        <p>转载请务必注明出处，原创不易！</p>
<p> 相关文章：<a href="http://blog.csdn.net/tzs_1041218129/article/details/53404326"><strong>通过项目逐步深入了解Mybatis&lt;一&gt;</strong></a><br>本项目全部代码地址：<a href="https://github.com/zhisheng17/mybatis"><strong>Github-Mybatis</strong></a></p>
<h3 id="Mybatis-解决-jdbc-编程的问题"><a href="#Mybatis-解决-jdbc-编程的问题" class="headerlink" title="Mybatis 解决 jdbc 编程的问题"></a>Mybatis 解决 jdbc 编程的问题</h3><p>1、  数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能，如果使用数据库链接池可解决此问题。</p>
<p>解决：在SqlMapConfig.xml中配置数据链接池，使用连接池管理数据库链接。</p>
<p>2、  Sql语句写在代码中造成代码不易维护，实际应用sql变化的可能较大，sql变动需要改变java代码。</p>
<p>解决：将Sql语句配置在XXXXmapper.xml文件中与java代码分离。</p>
<p>3、  向sql语句传参数麻烦，因为sql语句的where条件不一定，可能多也可能少，占位符需要和参数一一对应。</p>
<p>解决：Mybatis自动将java对象映射至sql语句，通过statement中的parameterType定义输入参数的类型。</p>
<p>4、  对结果集解析麻烦，sql变化导致解析代码变化，且解析前需要遍历，如果能将数据库记录封装成pojo对象解析比较方便。</p>
<p>解决：Mybatis自动将sql执行结果映射至java对象，通过statement中的resultType定义输出结果的类型。</p>
<a id="more"></a>
<h3 id="Mybatis-与-Hibernate-不同"><a href="#Mybatis-与-Hibernate-不同" class="headerlink" title="Mybatis 与 Hibernate 不同"></a>Mybatis 与 Hibernate 不同</h3><p>Mybatis和hibernate不同，它不完全是一个ORM框架，因为MyBatis需要程序员自己编写Sql语句，不过mybatis可以通过XML或注解方式灵活配置要运行的sql语句，并将java对象和sql语句映射生成最终执行的sql，最后将sql执行的结果再映射生成java对象。</p>
<p> Mybatis学习门槛低，简单易学，程序员直接编写原生态sql，可严格控制sql执行性能，灵活度高，非常适合对关系数据模型要求不高的软件开发，例如互联网软件、企业运营类软件等，因为这类软件需求变化频繁，一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性，如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件，工作量大。</p>
<p> Hibernate对象/关系映射能力强，数据库无关性好，对于关系模型要求高的软件（例如需求固定的定制化软件）如果用hibernate开发可以节省很多代码，提高效率。但是Hibernate的学习门槛高，要精通门槛更高，而且怎么设计O/R映射，在性能和对象模型之间如何权衡，以及怎样用好Hibernate需要具有很强的经验和能力才行。</p>
<p>总之，按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构，所以框架只有适合才是最好。</p>
<h2 id="Mybatis-开发-dao"><a href="#Mybatis-开发-dao" class="headerlink" title="Mybatis 开发 dao"></a>Mybatis 开发 dao</h2><h3 id="两种方法"><a href="#两种方法" class="headerlink" title="两种方法"></a>两种方法</h3><ul>
<li>原始 dao 开发方法（程序需要编写 dao 接口和 dao 实现类）（掌握）</li>
<li>Mybatis 的 mapper 接口（相当于 dao 接口）代理开发方法（掌握）</li>
</ul>
<h3 id="需求"><a href="#需求" class="headerlink" title="需求"></a>需求</h3><p>将下边的功能实现Dao：</p>
<ul>
<li>根据用户id查询一个用户信息</li>
<li>根据用户名称模糊查询用户信息列表</li>
<li>添加用户信息</li>
</ul>
<p>Mybatis 配置文件 SqlMapConfig.xml</p>
<h3 id="Sqlsession-的使用范围"><a href="#Sqlsession-的使用范围" class="headerlink" title="Sqlsession 的使用范围"></a>Sqlsession 的使用范围</h3><p>SqlSession 中封装了对数据库的操作，如：查询、插入、更新、删除等。</p>
<p>通过 SqlSessionFactory 创建 SqlSession，而 SqlSessionFactory 是通过 SqlSessionFactoryBuilder 进行创建。</p>
<h3 id="1、SqlSessionFactoryBuilder"><a href="#1、SqlSessionFactoryBuilder" class="headerlink" title="1、SqlSessionFactoryBuilder"></a>1、SqlSessionFactoryBuilder</h3><p>SqlSessionFactoryBuilder 用于创建 SqlSessionFacoty，SqlSessionFacoty 一旦创建完成就不需要SqlSessionFactoryBuilder 了，因为 SqlSession 是通过 SqlSessionFactory 生产，所以可以将SqlSessionFactoryBuilder 当成一个工具类使用，最佳使用范围是方法范围即方法体内局部变量。</p>
<h3 id="2、SqlSessionFactory"><a href="#2、SqlSessionFactory" class="headerlink" title="2、SqlSessionFactory"></a>2、SqlSessionFactory</h3><p>SqlSessionFactory 是一个接口，接口中定义了 openSession 的不同重载方法，SqlSessionFactory 的最佳使用范围是整个应用运行期间，一旦创建后可以重复使用，通常以单例模式管理 SqlSessionFactory。</p>
<h3 id="3、SqlSession"><a href="#3、SqlSession" class="headerlink" title="3、SqlSession"></a>3、SqlSession</h3><p>SqlSession 是一个面向用户的接口， sqlSession 中定义了数据库操作，默认使用 DefaultSqlSession 实现类。</p>
<p>执行过程如下：</p>
<p>1）、  加载数据源等配置信息</p>
<p>Environment environment = configuration.getEnvironment();</p>
<p>2）、  创建数据库链接</p>
<p>3）、  创建事务对象</p>
<p>4）、  创建Executor，SqlSession 所有操作都是通过 Executor 完成，mybatis 源码如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (ExecutorType.BATCH == executorType) &#123;</span><br><span class="line">      executor = newBatchExecutor(<span class="keyword">this</span>, transaction);</span><br><span class="line">    &#125; elseif (ExecutorType.REUSE == executorType) &#123;</span><br><span class="line">      executor = <span class="keyword">new</span> ReuseExecutor(<span class="keyword">this</span>, transaction);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      executor = <span class="keyword">new</span> SimpleExecutor(<span class="keyword">this</span>, transaction);</span><br><span class="line">    &#125;</span><br><span class="line"><span class="keyword">if</span> (cacheEnabled) &#123;</span><br><span class="line">      executor = <span class="keyword">new</span> CachingExecutor(executor, autoCommit);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>
<p>5）、  SqlSession的实现类即 DefaultSqlSession，此对象中对操作数据库实质上用的是 Executor</p>
<h3 id="结论："><a href="#结论：" class="headerlink" title="结论："></a>结论：</h3><pre><code>每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享使用，它也是线程不安全的。因此最佳的范围是请求或方法范围(定义局部变量使用)。绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中。

打开一个SqlSession；使用完毕就要关闭它。通常把这个关闭操作放到 finally 块中以确保每次都能执行关闭。如下：
</code></pre><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">SqlSession session = sqlSessionFactory.openSession();</span><br><span class="line">	try &#123;</span><br><span class="line"> 		 // do work</span><br><span class="line">	&#125; finally &#123;</span><br><span class="line">  		session.close();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="原始-Dao-开发方法"><a href="#原始-Dao-开发方法" class="headerlink" title="原始 Dao 开发方法"></a>原始 Dao 开发方法</h2><h3 id="思路："><a href="#思路：" class="headerlink" title="思路："></a>思路：</h3><p>需要程序员编写 Dao 接口和 Dao 实现类；</p>
<p>需要在 Dao 实现类中注入 SqlsessionFactory ，在方法体内通过 SqlsessionFactory 创建 Sqlsession。</p>
<h3 id="Dao接口"><a href="#Dao接口" class="headerlink" title="Dao接口"></a>Dao接口</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">UserDao</span>    //<span class="title">dao</span>接口，用户管理</span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="comment">//根据id查询用户信息</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> User <span class="title">findUserById</span><span class="params">(<span class="keyword">int</span> id)</span> <span class="keyword">throws</span> Exception</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//添加用户信息</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">addUser</span><span class="params">(User user)</span> <span class="keyword">throws</span> Exception</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//删除用户信息</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">deleteUser</span><span class="params">(<span class="keyword">int</span> id)</span> <span class="keyword">throws</span> Exception</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="Dao-实现类"><a href="#Dao-实现类" class="headerlink" title="Dao 实现类"></a>Dao 实现类</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">UserDaoImpl</span>  <span class="keyword">implements</span> <span class="title">UserDao</span>  //<span class="title">dao</span>接口实现类</span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="comment">//需要在 Dao 实现类中注入 SqlsessionFactory</span></span><br><span class="line">    <span class="comment">//这里通过构造方法注入</span></span><br><span class="line">    <span class="keyword">private</span> SqlSessionFactory sqlSessionFactory;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">UserDaoImpl</span><span class="params">(SqlSessionFactory sqlSessionFactory)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.sqlSessionFactory = sqlSessionFactory;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> User <span class="title">findUserById</span><span class="params">(<span class="keyword">int</span> id)</span> <span class="keyword">throws</span> Exception</span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="comment">//在方法体内通过 SqlsessionFactory 创建 Sqlsession</span></span><br><span class="line">        SqlSession sqlSession = sqlSessionFactory.openSession();</span><br><span class="line">        User user = sqlSession.selectOne(<span class="string">"test.findUserById"</span>, id);</span><br><span class="line">        sqlSession.close();</span><br><span class="line">        <span class="keyword">return</span> user;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">insertUser</span><span class="params">(User user)</span> <span class="keyword">throws</span> Exception</span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="comment">//在方法体内通过 SqlsessionFactory 创建 Sqlsession</span></span><br><span class="line">        SqlSession sqlSession = sqlSessionFactory.openSession();</span><br><span class="line">        <span class="comment">//执行插入的操作</span></span><br><span class="line">        sqlSession.insert(<span class="string">"test.insetrUser"</span>, user);</span><br><span class="line">        <span class="comment">//提交事务</span></span><br><span class="line">        sqlSession.commit();</span><br><span class="line">        <span class="comment">//释放资源</span></span><br><span class="line">        sqlSession.close();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">deleteUser</span><span class="params">(<span class="keyword">int</span> id)</span> <span class="keyword">throws</span> Exception</span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="comment">//在方法体内通过 SqlsessionFactory 创建 Sqlsession</span></span><br><span class="line">        SqlSession sqlSession = sqlSessionFactory.openSession();</span><br><span class="line">        sqlSession.delete(<span class="string">"test.deleteUserById"</span>, id);</span><br><span class="line">        <span class="comment">//提交事务</span></span><br><span class="line">        sqlSession.commit();</span><br><span class="line">        sqlSession.close();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="测试"><a href="#测试" class="headerlink" title="测试"></a>测试</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">UserDaoImplTest</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="keyword">private</span> SqlSessionFactory sqlSessionFactory;</span><br><span class="line">    <span class="comment">//此方法是在 testFindUserById 方法之前执行的</span></span><br><span class="line">    <span class="meta">@Before</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setup</span><span class="params">()</span> <span class="keyword">throws</span> Exception</span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="comment">//创建sqlSessionFactory</span></span><br><span class="line">        <span class="comment">//Mybatis 配置文件</span></span><br><span class="line">        String resource = <span class="string">"SqlMapConfig.xml"</span>;</span><br><span class="line">        <span class="comment">//得到配置文件流</span></span><br><span class="line">        InputStream inputStream = Resources.getResourceAsStream(resource);</span><br><span class="line">        <span class="comment">//创建会话工厂,传入Mybatis的配置文件信息</span></span><br><span class="line">        sqlSessionFactory = <span class="keyword">new</span> SqlSessionFactoryBuilder().build(inputStream);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testFindUserById</span><span class="params">()</span> <span class="keyword">throws</span> Exception</span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="comment">//创建UserDao的对象</span></span><br><span class="line">        UserDao userDao = <span class="keyword">new</span> UserDaoImpl(sqlSessionFactory);</span><br><span class="line">        <span class="comment">//调用UserDao方法</span></span><br><span class="line">        User user = userDao.findUserById(<span class="number">1</span>);</span><br><span class="line">        System.out.println(user);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>通过id查询用户信息测试结果如下：（其他的可以自己在写测试代码，原理类似）</p>
<p><img src="http://image.54tianzhisheng.cn/dao%E5%BC%80%E5%8F%91.jpg" alt=""></p>
<h3 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h3><p>原始Dao开发中存在以下问题：</p>
<ul>
<li>Dao方法体存在重复代码：通过 SqlSessionFactory 创建 SqlSession，调用 SqlSession 的数据库操作方法</li>
<li>调用 sqlSession 的数据库操作方法需要指定 statement 的i d，这里存在硬编码，不得于开发维护。</li>
<li>调用 sqlSession 的数据库操作方法时传入的变量，由于 sqlsession 方法使用泛型，即使变量类型传入错误，在编译阶段也不报错，不利于程序员开发。</li>
</ul>
<h2 id="Mybatis-的-mapper-接口"><a href="#Mybatis-的-mapper-接口" class="headerlink" title="Mybatis 的 mapper 接口"></a>Mybatis 的 mapper 接口</h2><h3 id="思路"><a href="#思路" class="headerlink" title="思路"></a>思路</h3><p>程序员需要编写 mapper.xml 映射文件</p>
<p>只需要程序员编写Mapper接口（相当于Dao接口），需遵循一些开发规范，mybatis 可以自动生成 mapper 接口类代理对象。</p>
<p>开发规范：</p>
<ul>
<li><p>在 mapper.xml 中 namespace 等于 mapper 接口地址</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">mapper</span> <span class="attr">namespace</span>=<span class="string">"cn.zhisheng.mybatis.mapper.UserMapper"</span>&gt;</span><span class="tag">&lt;/<span class="name">mapper</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>在 xxxmapper.java 接口中的方法名要与 xxxMapper.xml 中 statement 的 id 一致。</p>
</li>
<li><p>在 xxxmapper.java 接口中的输入参数类型要与 xxxMapper.xml 中 statement 的 parameterType 指定的参数类型一致。</p>
</li>
<li><p>在 xxxmapper.java 接口中的返回值类型要与 xxxMapper.xml 中 statement 的 resultType 指定的类型一致。</p>
<p><code>UserMapper.java</code></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//根据id查询用户信息</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> User <span class="title">findUserById</span><span class="params">(<span class="keyword">int</span> id)</span> <span class="keyword">throws</span> Exception</span>;</span><br></pre></td></tr></table></figure>
<p><code>UserMapper.xml</code></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">"findUserById"</span> <span class="attr">parameterType</span>=<span class="string">"int"</span> <span class="attr">resultType</span>=<span class="string">"cn.zhisheng.mybatis.po.User"</span>&gt;</span></span><br><span class="line">        select * from user where id = #&#123;1&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<h3 id="总结："><a href="#总结：" class="headerlink" title="总结："></a>总结：</h3><p>以上的开发规范主要是对下边的代码进行统一的生成：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">User user = sqlSession.selectOne(<span class="string">"test.findUserById"</span>, id);</span><br><span class="line">sqlSession.insert(<span class="string">"test.insetrUser"</span>, user);</span><br><span class="line">sqlSession.delete(<span class="string">"test.deleteUserById"</span>, id);</span><br><span class="line">List&lt;User&gt; list = sqlSession.selectList(<span class="string">"test.findUserByName"</span>, username);</span><br></pre></td></tr></table></figure>
<h3 id="测试-1"><a href="#测试-1" class="headerlink" title="测试"></a>测试</h3><p>测试之前记得在 SqlMapConfig.xml 文件中添加加载映射文件 UserMapper.xml：</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">mapper</span> <span class="attr">resource</span>=<span class="string">"mapper/UserMapper.xml"</span>/&gt;</span></span><br></pre></td></tr></table></figure>
<p>测试代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">UserMapperTest</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="keyword">private</span> SqlSessionFactory sqlSessionFactory;</span><br><span class="line">    <span class="comment">//此方法是在 testFindUserById 方法之前执行的</span></span><br><span class="line">    <span class="meta">@Before</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setup</span><span class="params">()</span> <span class="keyword">throws</span> Exception</span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="comment">//创建sqlSessionFactory</span></span><br><span class="line">        <span class="comment">//Mybatis 配置文件</span></span><br><span class="line">        String resource = <span class="string">"SqlMapConfig.xml"</span>;</span><br><span class="line">        <span class="comment">//得到配置文件流</span></span><br><span class="line">        InputStream inputStream = Resources.getResourceAsStream(resource);</span><br><span class="line">        <span class="comment">//创建会话工厂,传入Mybatis的配置文件信息</span></span><br><span class="line">        sqlSessionFactory = <span class="keyword">new</span> SqlSessionFactoryBuilder().build(inputStream);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testFindUserById</span><span class="params">()</span> <span class="keyword">throws</span> Exception</span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        SqlSession sqlSession = sqlSessionFactory.openSession();</span><br><span class="line">        <span class="comment">//创建usermapper对象,mybatis自动生成代理对象</span></span><br><span class="line">        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);</span><br><span class="line">        <span class="comment">//调用UserMapper的方法</span></span><br><span class="line">        User user = userMapper.findUserById(<span class="number">1</span>);</span><br><span class="line">        System.out.println(user);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>通过id查询用户信息测试结果如下：（其他的请自己根据上下文写测试代码，或者去看我 <a href="https://github.com/zhisheng17/mybatis">Github-Mybatis学习笔记</a> 上看我这个项目的全部代码）</p>
<p><img src="http://image.54tianzhisheng.cn/mapper%E5%BC%80%E5%8F%91.jpg" alt=""></p>
<p>通过姓名查询用户信息：</p>
<p><img src="http://image.54tianzhisheng.cn/mapper%E5%BC%80%E5%8F%912.jpg" alt=""></p>
<h3 id="代理对象内部调用-selectOne-或者-selectList"><a href="#代理对象内部调用-selectOne-或者-selectList" class="headerlink" title="代理对象内部调用 selectOne 或者 selectList"></a>代理对象内部调用 selectOne 或者 selectList</h3><ul>
<li>如果 mapper 方法返回单个 pojo 对象（非集合对象），代理对象内部通过 selectOne 查询数据库</li>
<li>如果 mapper 方法返回集合对象，代理对象内部通过 selectList 查询数据库</li>
</ul>
<h3 id="mapper接口方法参数只能有一个是否影响系统开发"><a href="#mapper接口方法参数只能有一个是否影响系统开发" class="headerlink" title="mapper接口方法参数只能有一个是否影响系统开发"></a>mapper接口方法参数只能有一个是否影响系统开发</h3><blockquote>
<p>mapper 接口方法参数只能有一个，系统是否不利于维护？</p>
<p>系统框架中，dao层的代码是被业务层公用的。</p>
<p>即使 mapper 接口只有一个参数，可以使用包装类型的 pojo 满足不同的业务方法的需求。</p>
<p>注意：持久层方法的参数可以包装类型、map…. ，service方法中不建议使用包装类型。（不利于业务层的可扩展性）</p>
</blockquote>
<h2 id="SqlMapConfig-xml-文件"><a href="#SqlMapConfig-xml-文件" class="headerlink" title="SqlMapConfig.xml 文件"></a>SqlMapConfig.xml 文件</h2><p>Mybatis 的全局配置变量，配置内容和顺序如下：</p>
<p>properties（属性）</p>
<p>settings（全局配置参数）</p>
<p>typeAliases（类型别名）</p>
<p>typeHandlers（类型处理器）</p>
<p>objectFactory（对象工厂）</p>
<p>plugins（插件）</p>
<p>environments（环境集合属性对象）</p>
<p>​    environment（环境子属性对象）</p>
<p>​        transactionManager（事务管理）</p>
<p>​        dataSource（数据源）</p>
<p>mappers（映射器）</p>
<h3 id="properties-属性"><a href="#properties-属性" class="headerlink" title="properties 属性"></a>properties 属性</h3><p>需求：将数据库连接参数单独配置在 db.properties 中，只需要在 SqlMapConfig.xml 中加载该配置文件 db.properties 的属性值。在 SqlMapConfig.xml 中就不需要直接对数据库的连接参数进行硬编码了。方便以后对参数进行统一的管理，其他的xml文件可以引用该 db.properties 。</p>
<p><code>db.properties</code></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">jdbc.driver=com.mysql.jdbc.Driver</span><br><span class="line">jdbc.url=jdbc:mysql://localhost:3306/mybatis_test?characterEncoding=utf-8</span><br><span class="line">jdbc.username=root</span><br><span class="line">jdbc.password=root</span><br></pre></td></tr></table></figure>
<p>那么 SqlMapConfig.xml 中的配置变成如下：</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--加载配置文件--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">properties</span> <span class="attr">resource</span>=<span class="string">"db.properties"</span>&gt;</span><span class="tag">&lt;/<span class="name">properties</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!-- 和spring整合后 environments配置将废除--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">environments</span> <span class="attr">default</span>=<span class="string">"development"</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">environment</span> <span class="attr">id</span>=<span class="string">"development"</span>&gt;</span></span><br><span class="line">            <span class="comment">&lt;!-- 使用jdbc事务管理,事务由 Mybatis 控制--&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">transactionManager</span> <span class="attr">type</span>=<span class="string">"JDBC"</span> /&gt;</span></span><br><span class="line">            <span class="comment">&lt;!-- 数据库连接池--&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">dataSource</span> <span class="attr">type</span>=<span class="string">"POOLED"</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"driver"</span> <span class="attr">value</span>=<span class="string">"$&#123;jdbc.driver&#125;"</span> /&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"url"</span> <span class="attr">value</span>=<span class="string">"$&#123;jdbc.url&#125;"</span> /&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"username"</span> <span class="attr">value</span>=<span class="string">"$&#123;jdbc.username&#125;"</span> /&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"password"</span> <span class="attr">value</span>=<span class="string">"$&#123;jdbc.password&#125;"</span> /&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">dataSource</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">environment</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">environments</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>配置完成后我们测试一下是否能够和刚才一样的能够成功呢？那么我就先在db.properties中把数据库密码故意改错，看是否是正确的？不出意外的话是会报错的。</p>
<p><img src="http://image.54tianzhisheng.cn/%E6%8A%A5%E9%94%99.jpg" alt=""></p>
<p>注意： MyBatis 将按照下面的顺序来加载属性：</p>
<ul>
<li>在 properties 元素体内定义的属性首先被读取。</li>
</ul>
<ul>
<li>然后会读取 properties 元素中 resource 或 url 加载的属性，它会覆盖已读取的同名属性。</li>
</ul>
<ul>
<li><p>最后读取 parameterType 传递的属性，它会覆盖已读取的同名属性。</p>
<p>因此，通过parameterType传递的属性具有最高优先级，resource或 url 加载的属性次之，最低优先级的是 properties 元素体内定义的属性。</p>
</li>
</ul>
<p>建议：</p>
<ul>
<li>不要在 properties 元素体内添加任何属性值，只将属性值定义在 db.properties 文件之中。</li>
<li>在  db.properties 文件之中定义的属性名要有一定的特殊性。如 xxx.xxx.xxx</li>
</ul>
<h3 id="settings（全局配置参数）"><a href="#settings（全局配置参数）" class="headerlink" title="settings（全局配置参数）"></a>settings（全局配置参数）</h3><p>Mybatis 框架在运行时可以调整一些运行参数</p>
<p>比如：开启二级缓存、开启延迟加载。。。</p>
<p><img src="http://image.54tianzhisheng.cn/setting.jpg" alt=""></p>
<h3 id="typeAliases（类型别名）"><a href="#typeAliases（类型别名）" class="headerlink" title="typeAliases（类型别名）"></a>typeAliases（类型别名）</h3><p>需求：</p>
<p>在mapper.xml中，定义很多的statement，statement需要parameterType指定输入参数的类型、需要resultType指定输出结果的映射类型。</p>
<p>如果在指定类型时输入类型全路径，不方便进行开发，可以针对parameterType或resultType指定的类型定义一些别名，在mapper.xml中通过别名定义，方便开发。</p>
<p><strong>Mybatis支持的别名：</strong></p>
<table>
<thead>
<tr>
<th style="text-align:center">别名</th>
<th style="text-align:center">映射的类型</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">_byte</td>
<td style="text-align:center">byte</td>
</tr>
<tr>
<td style="text-align:center">_long</td>
<td style="text-align:center">long</td>
</tr>
<tr>
<td style="text-align:center">_short</td>
<td style="text-align:center">short</td>
</tr>
<tr>
<td style="text-align:center">_int</td>
<td style="text-align:center">int</td>
</tr>
<tr>
<td style="text-align:center">_integer</td>
<td style="text-align:center">int</td>
</tr>
<tr>
<td style="text-align:center">_double</td>
<td style="text-align:center">double</td>
</tr>
<tr>
<td style="text-align:center">_float</td>
<td style="text-align:center">float</td>
</tr>
<tr>
<td style="text-align:center">_boolean</td>
<td style="text-align:center">boolean</td>
</tr>
<tr>
<td style="text-align:center">string</td>
<td style="text-align:center">String</td>
</tr>
<tr>
<td style="text-align:center">byte</td>
<td style="text-align:center">Byte</td>
</tr>
<tr>
<td style="text-align:center">long</td>
<td style="text-align:center">Long</td>
</tr>
<tr>
<td style="text-align:center">short</td>
<td style="text-align:center">Short</td>
</tr>
<tr>
<td style="text-align:center">int</td>
<td style="text-align:center">Integer</td>
</tr>
<tr>
<td style="text-align:center">integer</td>
<td style="text-align:center">Integer</td>
</tr>
<tr>
<td style="text-align:center">double</td>
<td style="text-align:center">Double</td>
</tr>
<tr>
<td style="text-align:center">float</td>
<td style="text-align:center">Float</td>
</tr>
<tr>
<td style="text-align:center">boolean</td>
<td style="text-align:center">Boolean</td>
</tr>
<tr>
<td style="text-align:center">date</td>
<td style="text-align:center">Date</td>
</tr>
<tr>
<td style="text-align:center">decimal</td>
<td style="text-align:center">BigDecimal</td>
</tr>
<tr>
<td style="text-align:center">bigdecimal</td>
<td style="text-align:center">BigDecimal</td>
</tr>
</tbody>
</table>
<p><strong>自定义别名：</strong></p>
<p>在 SqlMapConfig.xml 中配置：(设置别名)</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">typeAliases</span>&gt;</span></span><br><span class="line">	<span class="comment">&lt;!-- 单个别名定义 --&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">typeAlias</span> <span class="attr">alias</span>=<span class="string">"user"</span> <span class="attr">type</span>=<span class="string">"cn.zhisheng.mybatis.po.User"</span>/&gt;</span></span><br><span class="line">	<span class="comment">&lt;!-- 批量别名定义，扫描整个包下的类，别名为类名（首字母大写或小写都可以） --&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">package</span> <span class="attr">name</span>=<span class="string">"cn.zhisheng.mybatis.po"</span>/&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">package</span> <span class="attr">name</span>=<span class="string">"其它包"</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">typeAliases</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>在 UserMapper.xml 中引用别名：( resultType 为 user )</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">"findUserById"</span> <span class="attr">parameterType</span>=<span class="string">"int"</span> <span class="attr">resultType</span>=<span class="string">"user"</span>&gt;</span></span><br><span class="line">        select * from user where id = #&#123;id&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>测试结果：</p>
<p><img src="http://image.54tianzhisheng.cn/Test4.jpg" alt=""></p>
<h3 id="typeHandlers（类型处理器）"><a href="#typeHandlers（类型处理器）" class="headerlink" title="typeHandlers（类型处理器）"></a>typeHandlers（类型处理器）</h3><p>mybatis中通过typeHandlers完成jdbc类型和java类型的转换。</p>
<p> 通常情况下，mybatis提供的类型处理器满足日常需要，不需要自定义.</p>
<p>mybatis支持类型处理器：</p>
<table>
<thead>
<tr>
<th style="text-align:center">类型处理器</th>
<th style="text-align:center"><strong>Java</strong>类型</th>
<th style="text-align:center"><strong>JDBC</strong>类型</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">BooleanTypeHandler</td>
<td style="text-align:center">Boolean，boolean</td>
<td style="text-align:center">任何兼容的布尔值</td>
</tr>
<tr>
<td style="text-align:center">ByteTypeHandler</td>
<td style="text-align:center">Byte，byte</td>
<td style="text-align:center">任何兼容的数字或字节类型</td>
</tr>
<tr>
<td style="text-align:center">ShortTypeHandler</td>
<td style="text-align:center">Short，short</td>
<td style="text-align:center">任何兼容的数字或短整型</td>
</tr>
<tr>
<td style="text-align:center">IntegerTypeHandler</td>
<td style="text-align:center">Integer，int</td>
<td style="text-align:center">任何兼容的数字和整型</td>
</tr>
<tr>
<td style="text-align:center">LongTypeHandler</td>
<td style="text-align:center">Long，long</td>
<td style="text-align:center">任何兼容的数字或长整型</td>
</tr>
<tr>
<td style="text-align:center">FloatTypeHandler</td>
<td style="text-align:center">Float，float</td>
<td style="text-align:center">任何兼容的数字或单精度浮点型</td>
</tr>
<tr>
<td style="text-align:center">DoubleTypeHandler</td>
<td style="text-align:center">Double，double</td>
<td style="text-align:center">任何兼容的数字或双精度浮点型</td>
</tr>
<tr>
<td style="text-align:center">BigDecimalTypeHandler</td>
<td style="text-align:center">BigDecimal</td>
<td style="text-align:center">任何兼容的数字或十进制小数类型</td>
</tr>
<tr>
<td style="text-align:center">StringTypeHandler</td>
<td style="text-align:center">String</td>
<td style="text-align:center">CHAR和VARCHAR类型</td>
</tr>
<tr>
<td style="text-align:center">ClobTypeHandler</td>
<td style="text-align:center">String</td>
<td style="text-align:center">CLOB和LONGVARCHAR类型</td>
</tr>
<tr>
<td style="text-align:center">NStringTypeHandler</td>
<td style="text-align:center">String</td>
<td style="text-align:center">NVARCHAR和NCHAR类型</td>
</tr>
<tr>
<td style="text-align:center">NClobTypeHandler</td>
<td style="text-align:center">String</td>
<td style="text-align:center">NCLOB类型</td>
</tr>
<tr>
<td style="text-align:center">ByteArrayTypeHandler</td>
<td style="text-align:center">byte[]</td>
<td style="text-align:center">任何兼容的字节流类型</td>
</tr>
<tr>
<td style="text-align:center">BlobTypeHandler</td>
<td style="text-align:center">byte[]</td>
<td style="text-align:center">BLOB和LONGVARBINARY类型</td>
</tr>
<tr>
<td style="text-align:center">DateTypeHandler</td>
<td style="text-align:center">Date（java.util）</td>
<td style="text-align:center">TIMESTAMP类型</td>
</tr>
<tr>
<td style="text-align:center">DateOnlyTypeHandler</td>
<td style="text-align:center">Date（java.util）</td>
<td style="text-align:center">DATE类型</td>
</tr>
<tr>
<td style="text-align:center">TimeOnlyTypeHandler</td>
<td style="text-align:center">Date（java.util）</td>
<td style="text-align:center">TIME类型</td>
</tr>
<tr>
<td style="text-align:center">SqlTimestampTypeHandler</td>
<td style="text-align:center">Timestamp（java.sql）</td>
<td style="text-align:center">TIMESTAMP类型</td>
</tr>
<tr>
<td style="text-align:center">SqlDateTypeHandler</td>
<td style="text-align:center">Date（java.sql）</td>
<td style="text-align:center">DATE类型</td>
</tr>
<tr>
<td style="text-align:center">SqlTimeTypeHandler</td>
<td style="text-align:center">Time（java.sql）</td>
<td style="text-align:center">TIME类型</td>
</tr>
<tr>
<td style="text-align:center">ObjectTypeHandler</td>
<td style="text-align:center">任意</td>
<td style="text-align:center">其他或未指定类型</td>
</tr>
<tr>
<td style="text-align:center">EnumTypeHandler</td>
<td style="text-align:center">Enumeration类型</td>
<td style="text-align:center">VARCHAR-任何兼容的字符串类型，作为代码存储（而不是索引）。</td>
</tr>
</tbody>
</table>
<h3 id="mappers（映射器）"><a href="#mappers（映射器）" class="headerlink" title="mappers（映射器）"></a>mappers（映射器）</h3><ul>
<li><mapper resource=" " />

<p>使用相对于类路径的资源，如：<mapper resource="sqlmap/User.xml" /></p>
</li>
<li><mapper url=" " />

<p>使用完全限定路径<br>如：<mapper url="file://D:\workspace\mybatis\config\sqlmap\User.xml" /></p>
</li>
<li><mapper class=" " />

<p>使用 mapper 接口类路径</p>
<p>如：<mapper class="cn.zhisheng.mybatis.mapper.UserMapper"/></p>
<p>注意：此种方法要求 mapper 接口名称和 mapper 映射文件名称相同，且放在同一个目录中。</p>
</li>
<li><mapper name=" " />

<p>注册指定包下的所有mapper接口<br>如：<package name="cn.zhisheng.mybatis.mapper"/><br>注意：此种方法要求 mapper 接口名称和 mapper 映射文件名称相同，且放在同一个目录中。</p>
</li>
</ul>
<h2 id="Mapper-xml-映射文件"><a href="#Mapper-xml-映射文件" class="headerlink" title="Mapper.xml 映射文件"></a>Mapper.xml 映射文件</h2><p>Mapper.xml映射文件中定义了操作数据库的sql，每个sql是一个statement，映射文件是mybatis的核心。</p>
<h3 id="输入映射"><a href="#输入映射" class="headerlink" title="输入映射"></a>输入映射</h3><p>通过 parameterType 指定输入参数的类型，类型可以是简单类型、hashmap、pojo的包装类型。</p>
<p><strong>传递 pojo 包装对象</strong> （重点）</p>
<p>开发中通过pojo传递查询条件 ，查询条件是综合的查询条件，不仅包括用户查询条件还包括其它的查询条件（比如将用户购买商品信息也作为查询条件），这时可以使用包装对象传递输入参数。</p>
<ul>
<li><p>定义包装对象</p>
<p>定义包装对象将查询条件(pojo)以类组合的方式包装起来。</p>
<p><code>UserQueryVo.java</code></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">UserQueryVo</span>    //用户包装类型</span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="comment">//在这里包装所需要的查询条件</span></span><br><span class="line">    <span class="comment">//用户查询条件</span></span><br><span class="line">    <span class="keyword">private</span> UserCustom userCustom;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> UserCustom <span class="title">getUserCustom</span><span class="params">()</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> userCustom;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setUserCustom</span><span class="params">(UserCustom userCustom)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.userCustom = userCustom;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//还可以包装其他的查询条件，比如订单、商品</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><code>UserCustomer.java</code></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">UserCustom</span> <span class="keyword">extends</span> <span class="title">User</span>    //用户的扩展类</span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="comment">//可以扩展用户的信息</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p><code>UserMapper.xml</code> 文件</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--用户信息综合查询</span></span><br><span class="line"><span class="comment">    #&#123;userCustom.sex&#125; :取出pojo包装对象中的性别值</span></span><br><span class="line"><span class="comment">    #&#123;userCustom.username&#125; :取出pojo包装对象中的用户名称</span></span><br><span class="line"><span class="comment">    --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">"findUserList"</span> <span class="attr">parameterType</span>=<span class="string">"cn.zhisheng.mybatis.po.UserQueryVo"</span> <span class="attr">resultType</span>=<span class="string">"cn.zhisheng.mybatis.po.UserCustom"</span>&gt;</span></span><br><span class="line">        select * from user where user.sex = #&#123;userCustom.sex&#125; and user.username like  '%$&#123;userCustom.username&#125;%'</span><br><span class="line">    <span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>UserMapper.java</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//用户信息综合查询</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;UserCustom&gt; <span class="title">findUserList</span><span class="params">(UserQueryVo userQueryVo)</span> <span class="keyword">throws</span> Exception</span>;</span><br></pre></td></tr></table></figure>
</li>
<li><p>测试代码</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//测试用户信息综合查询</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testFindUserList</span><span class="params">()</span> <span class="keyword">throws</span> Exception</span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        SqlSession sqlSession = sqlSessionFactory.openSession();</span><br><span class="line">        <span class="comment">//创建usermapper对象,mybatis自动生成代理对象</span></span><br><span class="line">        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);</span><br><span class="line">        <span class="comment">//创建包装对象，设置查询条件</span></span><br><span class="line">        UserQueryVo userQueryVo = <span class="keyword">new</span> UserQueryVo();</span><br><span class="line">        UserCustom userCustom = <span class="keyword">new</span> UserCustom();</span><br><span class="line">        userCustom.setSex(<span class="string">"男"</span>);</span><br><span class="line">        userCustom.setUsername(<span class="string">"张小明"</span>);</span><br><span class="line">        userQueryVo.setUserCustom(userCustom);</span><br><span class="line">        <span class="comment">//调用UserMapper的方法</span></span><br><span class="line">        List&lt;UserCustom&gt; list = userMapper.findUserList(userQueryVo);</span><br><span class="line">        System.out.println(list);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>测试结果</p>
<p><img src="http://image.54tianzhisheng.cn/Test5.jpg" alt=""></p>
</li>
</ul>
<h3 id="输出映射"><a href="#输出映射" class="headerlink" title="输出映射"></a>输出映射</h3><ul>
<li><strong>resultType</strong></li>
</ul>
<blockquote>
<ul>
<li><strong>使用 resultType 进行输出映射，只有查询出来的列名和 pojo 中的属性名一致，该列才可以映射成功。</strong></li>
<li>如果查询出来的列名和 pojo 中的属性名全部不一致，没有创建 pojo 对象。</li>
<li>只要查询出来的列名和 pojo 中的属性有一个一致，就会创建 pojo 对象。</li>
</ul>
</blockquote>
<h4 id="输出简单类型"><a href="#输出简单类型" class="headerlink" title="输出简单类型"></a>输出简单类型</h4><p>需求：用户信息综合查询列表总数，通过查询总数和上边用户综合查询列表才可以实现分页</p>
<p>实现：</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--用户信息综合查询总数</span></span><br><span class="line"><span class="comment">    parameterType:指定输入的类型和findUserList一样</span></span><br><span class="line"><span class="comment">    resultType:输出结果类型为 int</span></span><br><span class="line"><span class="comment">    --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">"findUserCount"</span> <span class="attr">parameterType</span>=<span class="string">"cn.zhisheng.mybatis.po.UserQueryVo"</span> <span class="attr">resultType</span>=<span class="string">"int"</span>&gt;</span></span><br><span class="line">      select count(*) from user where user.sex = #&#123;userCustom.sex&#125; and user.username like  '%$&#123;userCustom.username&#125;%'</span><br><span class="line">    <span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//用户信息综合查询总数</span></span><br><span class="line">   <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findUserCount</span><span class="params">(UserQueryVo userQueryVo)</span> <span class="keyword">throws</span> Exception</span>;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//测试用户信息综合查询总数</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testFindUserCount</span><span class="params">()</span> <span class="keyword">throws</span> Exception</span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        SqlSession sqlSession = sqlSessionFactory.openSession();</span><br><span class="line">        <span class="comment">//创建usermapper对象,mybatis自动生成代理对象</span></span><br><span class="line">        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);</span><br><span class="line">        <span class="comment">//创建包装对象，设置查询条件</span></span><br><span class="line">        UserQueryVo userQueryVo = <span class="keyword">new</span> UserQueryVo();</span><br><span class="line">        UserCustom userCustom = <span class="keyword">new</span> UserCustom();</span><br><span class="line">        userCustom.setSex(<span class="string">"男"</span>);</span><br><span class="line">        userCustom.setUsername(<span class="string">"张小明"</span>);</span><br><span class="line">        userQueryVo.setUserCustom(userCustom);</span><br><span class="line">        <span class="comment">//调用UserMapper的方法</span></span><br><span class="line">        System.out.println(userMapper.findUserCount(userQueryVo));</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>
<p><img src="http://image.54tianzhisheng.cn/Test6.jpg" alt=""></p>
<p>注意：查询出来的结果集只有一行且一列，可以使用简单类型进行输出映射。</p>
<p><strong>输出pojo对象和pojo列表</strong></p>
<p>不管是输出的pojo单个对象还是一个列表（list中包括pojo），在mapper.xml中resultType指定的类型是一样的。</p>
<p>在mapper.java指定的方法返回值类型不一样：</p>
<p>1、输出单个pojo对象，方法返回值是单个对象类型</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//根据id查询用户信息</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> User <span class="title">findUserById</span><span class="params">(<span class="keyword">int</span> id)</span> <span class="keyword">throws</span> Exception</span>;</span><br></pre></td></tr></table></figure>
<p>2、输出pojo对象list，方法返回值是List<Pojo></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//根据用户名查询用户信息</span></span><br><span class="line">  <span class="function"><span class="keyword">public</span> List&lt;User&gt; <span class="title">findUserByUsername</span><span class="params">(String userName)</span> <span class="keyword">throws</span>  Exception</span>;</span><br></pre></td></tr></table></figure>
<p> resultType总结：</p>
<p>输出pojo对象和输出pojo列表在sql中定义的resultType是一样的。</p>
<p>返回单个pojo对象要保证sql查询出来的结果集为单条，内部使用session.selectOne方法调用，mapper接口使用pojo对象作为方法返回值。</p>
<p>返回pojo列表表示查询出来的结果集可能为多条，内部使用session.selectList方法，mapper接口使用List<pojo>对象作为方法返回值。</p>
<ul>
<li><strong>resultMap</strong></li>
</ul>
<p>resultType 可以指定 pojo 将查询结果映射为 pojo，但需要 pojo 的属性名和 sql 查询的列名一致方可映射成功。</p>
<p>如果sql查询字段名和pojo的属性名不一致，可以通过resultMap将字段名和属性名作一个对应关系 ，resultMap实质上还需要将查询结果映射到pojo对象中。</p>
<p>resultMap可以实现将查询结果映射为复杂类型的pojo，比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。</p>
<p>使用方法：</p>
<p>1、定义 resultMap</p>
<p>2、使用 resultMap 作为 statement 的输出映射类型</p>
<p>将下面的 sql 使用 User 完成映射</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> <span class="keyword">id</span> id_, username username_ <span class="keyword">from</span> <span class="keyword">user</span> <span class="keyword">where</span> <span class="keyword">id</span> = #&#123;<span class="keyword">value</span>&#125;</span><br></pre></td></tr></table></figure>
<p>User 类中属性名和上边查询的列名不一致。</p>
<p>所以需要：</p>
<p>1、定义 resultMap</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--定义 resultMap</span></span><br><span class="line"><span class="comment">    将select id id_, username username_ from user where id = #&#123;value&#125; 和User类中的属性做一个映射关系</span></span><br><span class="line"><span class="comment">    type: resultMap最终映射的java对象类型</span></span><br><span class="line"><span class="comment">    id:对resultMap的唯一标识</span></span><br><span class="line"><span class="comment">    --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">resultMap</span> <span class="attr">id</span>=<span class="string">"userResultMap"</span> <span class="attr">type</span>=<span class="string">"user"</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--id表示查询结果中的唯一标识</span></span><br><span class="line"><span class="comment">        column：查询出来的列名</span></span><br><span class="line"><span class="comment">        property：type指定pojo的属性名</span></span><br><span class="line"><span class="comment">        最终resultMap对column和property做一个映射关系（对应关系）</span></span><br><span class="line"><span class="comment">        --&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">id</span> <span class="attr">column</span>=<span class="string">"id_"</span> <span class="attr">property</span>=<span class="string">"id"</span>/&gt;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">&lt;!--result: 对普通结果映射定义</span></span><br><span class="line"><span class="comment">        column：查询出来的列名</span></span><br><span class="line"><span class="comment">        property：type指定pojo的属性名</span></span><br><span class="line"><span class="comment">        最终resultMap对column和property做一个映射关系（对应关系）</span></span><br><span class="line"><span class="comment">        --&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">result</span> <span class="attr">column</span>=<span class="string">"username_"</span> <span class="attr">property</span>=<span class="string">"username"</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">resultMap</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>2、使用 resultMap 作为 statement 的输出映射类型</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--使用 resultMap 作为输出映射类型</span></span><br><span class="line"><span class="comment">        resultMap="userResultMap":其中的userResultMap就是我们刚才定义的 resultMap 的id值,如果这个resultMap在其他的mapper文件中，前边须加上namespace --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">"findUserByIdResultMap"</span> <span class="attr">parameterType</span>=<span class="string">"int"</span> <span class="attr">resultMap</span>=<span class="string">"userResultMap"</span>&gt;</span></span><br><span class="line">        select id id_, username username_ from user where id = #&#123;value&#125;</span><br><span class="line">    <span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>3、<code>UserMapper.java</code></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">//根据id查询用户信息，使用 resultMap 输出</span><br><span class="line">public User findUserByIdResultMap(int id) throws Exception;</span><br></pre></td></tr></table></figure>
<p>4、测试</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//测试根据id查询用户信息，使用 resultMap 输出</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testFindUserByIdResultMap</span><span class="params">()</span> <span class="keyword">throws</span> Exception</span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        SqlSession sqlSession = sqlSessionFactory.openSession();</span><br><span class="line">        <span class="comment">//创建usermapper对象,mybatis自动生成代理对象</span></span><br><span class="line">        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);</span><br><span class="line">        <span class="comment">//调用UserMapper的方法</span></span><br><span class="line">        User user = userMapper.findUserByIdResultMap(<span class="number">1</span>);</span><br><span class="line">        System.out.println(user);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>
<p>5、测试结果</p>
<p><img src="http://image.54tianzhisheng.cn/Test7.jpg" alt=""></p>
<h2 id="动态-SQL"><a href="#动态-SQL" class="headerlink" title="动态 SQL"></a>动态 SQL</h2><p>通过mybatis提供的各种标签方法实现动态拼接sql。</p>
<p>需求：</p>
<p>用户信息综合查询列表和用户信息查询列表总数这两个 statement的定义使用动态sql。</p>
<p>对查询条件进行判断，如果输入的参数不为空才进行查询条件拼接。</p>
<p><code>UserMapper.xml</code> (findUserList的配置如下，那么findUserCount的也是一样的，这里就不全部写出来了)</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span> <span class="attr">id</span>=<span class="string">"findUserList"</span> <span class="attr">parameterType</span>=<span class="string">"cn.zhisheng.mybatis.po.UserQueryVo"</span> <span class="attr">resultType</span>=<span class="string">"cn.zhisheng.mybatis.po.UserCustom"</span>&gt;</span></span><br><span class="line">        select * from user</span><br><span class="line">        <span class="comment">&lt;!--where可以自动的去掉条件中的第一个and--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">where</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">"userCustom != null"</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">"userCustom.sex != null and userCustom.sex != ''"</span>&gt;</span></span><br><span class="line">                    and user.sex = #&#123;userCustom.sex&#125;</span><br><span class="line">                <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">"userCustom.username != null"</span>&gt;</span></span><br><span class="line">                    and user.username like  '%$&#123;userCustom.username&#125;%'</span><br><span class="line">                <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">where</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>测试代码：因为设置了动态的sql，如果不设置某个值，那么条件就不会拼接在sql上</p>
<p>所以我们就注释掉设置username的语句</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//userCustom.setUsername("张小明");</span></span><br></pre></td></tr></table></figure>
<p>测试结果：</p>
<p><img src="http://image.54tianzhisheng.cn/Test8.jpg" alt=""></p>
<h3 id="Sql-片段"><a href="#Sql-片段" class="headerlink" title="Sql 片段"></a>Sql 片段</h3><p>通过上面的其实看到在 where sql语句中有很多重复代码，我们可以将其抽取出来，组成一个sql片段，其他的statement就可以引用这个sql片段，利于系统的开发。</p>
<p>这里我们就拿上边sql 中的where定义一个sq片段如下：</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--sql片段</span></span><br><span class="line"><span class="comment">   id:唯一标识</span></span><br><span class="line"><span class="comment">   经验：是基于单表来定义sql片段，这样的话sql片段的可重用性才高</span></span><br><span class="line"><span class="comment">   一般不包含where</span></span><br><span class="line"><span class="comment">   --&gt;</span></span><br><span class="line">   <span class="tag">&lt;<span class="name">sql</span> <span class="attr">id</span>=<span class="string">"query_user_where"</span>&gt;</span></span><br><span class="line">       <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">"userCustom != null"</span>&gt;</span></span><br><span class="line">           <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">"userCustom.sex != null and userCustom.sex != ''"</span>&gt;</span></span><br><span class="line">               and user.sex = #&#123;userCustom.sex&#125;</span><br><span class="line">           <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">           <span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">"userCustom.username != null"</span>&gt;</span></span><br><span class="line">               and user.username like  '%$&#123;userCustom.username&#125;%'</span><br><span class="line">           <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">       <span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br><span class="line">   <span class="tag">&lt;/<span class="name">sql</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>那么我们该怎样引用这个sql片段呢？如下：</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">select * from user</span><br><span class="line">        <span class="tag">&lt;<span class="name">where</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--refid: 指定sql片段的id，如果是写在其他的mapper文件中，则需要在前面加上namespace--&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">include</span> <span class="attr">refid</span>=<span class="string">"query_user_where"</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">where</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>测试的话还是那样了，就不继续说了，前面已经说了很多了。</p>
<h3 id="foreach"><a href="#foreach" class="headerlink" title="foreach"></a>foreach</h3><p>向sql传递数组或List，mybatis使用foreach解析</p>
<p>需求：</p>
<p>在用户查询列表和查询总数的statement中增加多个id输入查询。</p>
<p>sql语句如下：</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> <span class="keyword">USER</span> <span class="keyword">WHERE</span> <span class="keyword">id</span>=<span class="number">1</span> <span class="keyword">OR</span> <span class="keyword">id</span>=<span class="number">10</span> ORid=<span class="number">16</span></span><br><span class="line">或者</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> <span class="keyword">USER</span> <span class="keyword">WHERE</span> <span class="keyword">id</span> <span class="keyword">IN</span>(<span class="number">1</span>,<span class="number">10</span>,<span class="number">16</span>)</span><br></pre></td></tr></table></figure>
<p>在输入参数类型中添加 List<Integer> ids 传入多个 id</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">UserQueryVo</span>    //用户包装类型</span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="comment">//传入多个id</span></span><br><span class="line">    <span class="keyword">private</span> List&lt;Integer&gt; ids;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>修改 UserMapper.xml文件</p>
<p>WHERE id=1 OR id=10 OR id=16</p>
<p>在查询条件中，查询条件定义成一个sql片段，需要修改sql片段。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">if</span> <span class="attr">test</span>=<span class="string">"ids!=null"</span>&gt;</span></span><br><span class="line">			<span class="comment">&lt;!-- 使用 foreach遍历传入ids</span></span><br><span class="line"><span class="comment">			collection：指定输入 对象中集合属性</span></span><br><span class="line"><span class="comment">			item：每个遍历生成对象中</span></span><br><span class="line"><span class="comment">			open：开始遍历时拼接的串</span></span><br><span class="line"><span class="comment">			close：结束遍历时拼接的串</span></span><br><span class="line"><span class="comment">			separator：遍历的两个对象中需要拼接的串</span></span><br><span class="line"><span class="comment">			 --&gt;</span></span><br><span class="line">			 <span class="comment">&lt;!-- 使用实现下边的sql拼接：</span></span><br><span class="line"><span class="comment">			  AND (id=1 OR id=10 OR id=16)</span></span><br><span class="line"><span class="comment">			  --&gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">foreach</span> <span class="attr">collection</span>=<span class="string">"ids"</span> <span class="attr">item</span>=<span class="string">"user_id"</span> <span class="attr">open</span>=<span class="string">"AND ("</span> <span class="attr">close</span>=<span class="string">")"</span> <span class="attr">separator</span>=<span class="string">"or"</span>&gt;</span></span><br><span class="line">				<span class="comment">&lt;!-- 每个遍历需要拼接的串 --&gt;</span></span><br><span class="line">				id=#&#123;user_id&#125;</span><br><span class="line">			<span class="tag">&lt;/<span class="name">foreach</span>&gt;</span></span><br><span class="line"></span><br><span class="line">			<span class="comment">&lt;!-- 实现  “ and id IN(1,10,16)”拼接 --&gt;</span></span><br><span class="line">			<span class="comment">&lt;!-- &lt;foreach collection="ids" item="user_id" open="and id IN(" close=")" separator=","&gt;</span></span><br><span class="line"><span class="comment">				每个遍历需要拼接的串</span></span><br><span class="line"><span class="comment">				#&#123;user_id&#125;</span></span><br><span class="line"><span class="comment">			&lt;/foreach&gt; --&gt;</span></span><br><span class="line">			<span class="tag">&lt;/<span class="name">if</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>测试代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"> <span class="comment">//传入多个id</span></span><br><span class="line">List&lt;Integer&gt; ids = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">ids.add(<span class="number">1</span>);</span><br><span class="line">ids.add(<span class="number">10</span>);</span><br><span class="line">ids.add(<span class="number">16</span>);</span><br><span class="line"><span class="comment">//将ids传入statement中</span></span><br><span class="line">userQueryVo.setIds(ids);</span><br></pre></td></tr></table></figure>
<p>期待后续的文章吧！</p>
<p><img src="https://ws3.sinaimg.cn/large/006tNc79gy1fp3jkmizmpj30o00didgn.jpg" alt=""></p>

      
      
        <div class="page-reward">
          <p><a href="javascript:void(0)" onclick="dashangToggle()" class="dashang">赏</a></p>
          <div class="hide_box"></div>
          <div class="shang_box">
            <a class="shang_close" href="javascript:void(0)" onclick="dashangToggle()">×</a>
            <div class="shang_tit">
              <p>纯属好玩</p>
            </div>
            <div class="shang_payimg">
              <img src="/img/alipayimg.jpg" alt="扫码支持" title="扫一扫" />
            </div>
              <div class="pay_explain">扫码打赏，你说多少就多少</div>
            <div class="shang_payselect">
              
                <div class="pay_item checked" data-id="alipay">
                  <span class="radiobox"></span>
                  <span class="pay_logo"><img src="/img/alipay.png" alt="支付宝" /></span>
                </div>
              
              
                <div class="pay_item" data-id="wechat">
                  <span class="radiobox"></span>
                  <span class="pay_logo"><img src="/img/weixin.png" alt="微信" /></span>
                </div>
              
            </div>
            <div class="shang_info">
              <p>打开<span id="shang_pay_txt">支付宝</span>扫一扫，即可进行扫码打赏哦</p>
            </div>
          </div>
        </div>
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
        <script type="text/javascript">
          $(".pay_item").click(function(){
            $(this).addClass('checked').siblings('.pay_item').removeClass('checked');
            var dataid=$(this).attr('data-id');
            $(".shang_payimg img").attr("src","/img/"+dataid+"img.jpg");
            $("#shang_pay_txt").text(dataid=="alipay"?"支付宝":"微信");
          });
          function dashangToggle(){
            
            $(".hide_box").fadeToggle();
            $(".shang_box").fadeToggle();
          }
        </script>
      
    </div>
    
  </div>
  
    
    <div class="copyright">
        <p><span>本文标题:</span><a href="/2017/06/13/通过项目逐步深入了解Mybatis(二)/">通过项目逐步深入了解Mybatis（二）</a></p>
        <p><span>文章作者:</span><a href="/" title="访问 zhisheng 的个人博客">zhisheng</a></p>
        <p><span>发布时间:</span>2017年06月13日 - 00时00分</p>
        <p><span>最后更新:</span>2018年11月22日 - 22时51分</p>
        <p>
            <span>原始链接:</span><a class="post-url" href="/2017/06/13/通过项目逐步深入了解Mybatis(二)/" title="通过项目逐步深入了解Mybatis（二）">http://www.54tianzhisheng.cn/2017/06/13/通过项目逐步深入了解Mybatis(二)/</a>
            <span class="copy-path" data-clipboard-text="原文: http://www.54tianzhisheng.cn/2017/06/13/通过项目逐步深入了解Mybatis(二)/　　作者: zhisheng" title="点击复制文章链接"><i class="fa fa-clipboard"></i></span>
            <script src="/js/clipboard.min.js"></script>
            <script> var clipboard = new Clipboard('.copy-path'); </script>
        </p>
        <p>
            <span>许可协议:</span><i class="fa fa-creative-commons"></i> <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/cn/" title="中国大陆 (CC BY-NC-SA 3.0 CN)" target = "_blank">"署名-非商用-相同方式共享 3.0"</a> 转载请保留原文链接及作者。
        </p>
    </div>



<nav id="article-nav">
  
    <a href="/2017/06/13/Python爬虫实战之爬取糗事百科段子/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption"><</strong>
      <div class="article-nav-title">
        
          Python爬虫实战之爬取糗事百科段子
        
      </div>
    </a>
  
  
    <a href="/2017/06/13/Pyspider框架 —— Python爬虫实战之爬取 V2EX 网站帖子/" id="article-nav-older" class="article-nav-link-wrap">
      <div class="article-nav-title">Pyspider框架 —— Python爬虫实战之爬取 V2EX 网站帖子</div>
      <strong class="article-nav-caption">></strong>
    </a>
  
</nav>

  
</article>

    <div id="toc" class="toc-article">
    <strong class="toc-title">文章目录</strong>
    <ol class="toc"><li class="toc-item toc-level-3"><a class="toc-link" href="#Mybatis-解决-jdbc-编程的问题"><span class="toc-number">1.</span> <span class="toc-text">Mybatis 解决 jdbc 编程的问题</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Mybatis-与-Hibernate-不同"><span class="toc-number">2.</span> <span class="toc-text">Mybatis 与 Hibernate 不同</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Mybatis-开发-dao"><span class="toc-number"></span> <span class="toc-text">Mybatis 开发 dao</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#两种方法"><span class="toc-number">1.</span> <span class="toc-text">两种方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#需求"><span class="toc-number">2.</span> <span class="toc-text">需求</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Sqlsession-的使用范围"><span class="toc-number">3.</span> <span class="toc-text">Sqlsession 的使用范围</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1、SqlSessionFactoryBuilder"><span class="toc-number">4.</span> <span class="toc-text">1、SqlSessionFactoryBuilder</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2、SqlSessionFactory"><span class="toc-number">5.</span> <span class="toc-text">2、SqlSessionFactory</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3、SqlSession"><span class="toc-number">6.</span> <span class="toc-text">3、SqlSession</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#结论："><span class="toc-number">7.</span> <span class="toc-text">结论：</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#原始-Dao-开发方法"><span class="toc-number"></span> <span class="toc-text">原始 Dao 开发方法</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#思路："><span class="toc-number">1.</span> <span class="toc-text">思路：</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Dao接口"><span class="toc-number">2.</span> <span class="toc-text">Dao接口</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Dao-实现类"><span class="toc-number">3.</span> <span class="toc-text">Dao 实现类</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#测试"><span class="toc-number">4.</span> <span class="toc-text">测试</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#问题"><span class="toc-number">5.</span> <span class="toc-text">问题</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Mybatis-的-mapper-接口"><span class="toc-number"></span> <span class="toc-text">Mybatis 的 mapper 接口</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#思路"><span class="toc-number">1.</span> <span class="toc-text">思路</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#总结："><span class="toc-number">2.</span> <span class="toc-text">总结：</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#测试-1"><span class="toc-number">3.</span> <span class="toc-text">测试</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#代理对象内部调用-selectOne-或者-selectList"><span class="toc-number">4.</span> <span class="toc-text">代理对象内部调用 selectOne 或者 selectList</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#mapper接口方法参数只能有一个是否影响系统开发"><span class="toc-number">5.</span> <span class="toc-text">mapper接口方法参数只能有一个是否影响系统开发</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#SqlMapConfig-xml-文件"><span class="toc-number"></span> <span class="toc-text">SqlMapConfig.xml 文件</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#properties-属性"><span class="toc-number">1.</span> <span class="toc-text">properties 属性</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#settings（全局配置参数）"><span class="toc-number">2.</span> <span class="toc-text">settings（全局配置参数）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#typeAliases（类型别名）"><span class="toc-number">3.</span> <span class="toc-text">typeAliases（类型别名）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#typeHandlers（类型处理器）"><span class="toc-number">4.</span> <span class="toc-text">typeHandlers（类型处理器）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#mappers（映射器）"><span class="toc-number">5.</span> <span class="toc-text">mappers（映射器）</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Mapper-xml-映射文件"><span class="toc-number"></span> <span class="toc-text">Mapper.xml 映射文件</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#输入映射"><span class="toc-number">1.</span> <span class="toc-text">输入映射</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#输出映射"><span class="toc-number">2.</span> <span class="toc-text">输出映射</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#输出简单类型"><span class="toc-number">2.1.</span> <span class="toc-text">输出简单类型</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#动态-SQL"><span class="toc-number"></span> <span class="toc-text">动态 SQL</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Sql-片段"><span class="toc-number">1.</span> <span class="toc-text">Sql 片段</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#foreach"><span class="toc-number">2.</span> <span class="toc-text">foreach</span></a></li></ol>
</div>
<input type="button" id="tocButton" value="隐藏目录"  title="点击按钮隐藏或者显示文章目录">

<script src="https://7.url.cn/edu/jslib/comb/require-2.1.6,jquery-1.9.1.min.js"></script>
<script>
    var valueHide = "隐藏目录";
    var valueShow = "显示目录";

    if ($(".left-col").is(":hidden")) {
        $("#tocButton").attr("value", valueShow);
    }
    $("#tocButton").click(function() {
        if ($("#toc").is(":hidden")) {
            $("#tocButton").attr("value", valueHide);
            $("#toc").slideDown(320);
        }
        else {
            $("#tocButton").attr("value", valueShow);
            $("#toc").slideUp(350);
        }
    })
    if ($(".toc").length < 1) {
        $("#toc, #tocButton").hide();
    }
</script>





<div class="bdsharebuttonbox">
	<a href="#" class="fx fa-weibo bds_tsina" data-cmd="tsina" title="分享到新浪微博"></a>
	<a href="#" class="fx fa-weixin bds_weixin" data-cmd="weixin" title="分享到微信"></a>
	<a href="#" class="fx fa-qq bds_sqq" data-cmd="sqq" title="分享到QQ好友"></a>
	<a href="#" class="fx fa-facebook-official bds_fbook" data-cmd="fbook" title="分享到Facebook"></a>
	<a href="#" class="fx fa-twitter bds_twi" data-cmd="twi" title="分享到Twitter"></a>
	<a href="#" class="fx fa-linkedin bds_linkedin" data-cmd="linkedin" title="分享到linkedin"></a>
	<a href="#" class="fx fa-files-o bds_copy" data-cmd="copy" title="分享到复制网址"></a>
</div>
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"2","bdSize":"24"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>




    
        <div id="gitments"></div>
<script src="/js/gitment.browser.js"></script>
<script>
    var gitment = new Gitment({
      id: window.location.pathname,
      owner: 'zhisheng',
      repo: 'zhisheng17.github.io',
      oauth: {
        client_id: '',
        client_secret: '',
      },
    })
    gitment.render('gitments')
</script>
    



    <div class="scroll" id="post-nav-button">
        
            <a href="/2017/06/13/Python爬虫实战之爬取糗事百科段子/" title="上一篇: Python爬虫实战之爬取糗事百科段子">
                <i class="fa fa-angle-left"></i>
            </a>
        
        <a title="文章列表"><i class="fa fa-bars"></i><i class="fa fa-times"></i></a>
        
            <a href="/2017/06/13/Pyspider框架 —— Python爬虫实战之爬取 V2EX 网站帖子/" title="下一篇: Pyspider框架 —— Python爬虫实战之爬取 V2EX 网站帖子">
                <i class="fa fa-angle-right"></i>
            </a>
        
    </div>
    <ul class="post-list"><li class="post-list-item"><a class="post-list-link" href="/2019/01/06/Flink-Kafka-sink/">《从0到1学习Flink》—— Flink 写入数据到 Kafka</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/01/05/Flink-run/">《从0到1学习Flink》—— Flink 项目如何运行？</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/12/30/Flink-ElasticSearch-Sink/">《从0到1学习Flink》—— Flink 写入数据到 ElasticSearch</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/12/11/Flink-time/">《从0到1学习Flink》—— Flink 中几种 Time 详解</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/12/08/Flink-Stream-Windows/">《从0到1学习Flink》—— 介绍Flink中的Stream Windows</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/11/04/Flink-Data-transformation/">《从0到1学习Flink》—— Flink Data transformation(转换)</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/10/31/flink-create-sink/">《从0到1学习Flink》—— 如何自定义 Data Sink ？</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/10/30/flink-create-source/">《从0到1学习Flink》—— 如何自定义 Data Source ？</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/10/29/flink-sink/">《从0到1学习Flink》—— Data Sink 介绍</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/10/28/flink-sources/">《从0到1学习Flink》—— Data Source 介绍</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/10/27/flink-config/">《从0到1学习Flink》—— Flink 配置文件详解</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/10/13/flink-introduction/">《从0到1学习Flink》—— Apache Flink 介绍</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/09/18/flink-install/">《从0到1学习Flink》—— Mac 上搭建 Flink 1.6.0 环境并构建运行简单程序入门</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/08/30/go-sync/">Go 并发——实现协程同步的几种方式</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/08/14/idea-remote-debug-elasticsearch/">教你如何在 IDEA 远程 Debug ElasticSearch</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/08/12/es-code03/">渣渣菜鸡的 ElasticSearch 源码解析 —— 启动流程（下）</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/08/11/es-code02/">渣渣菜鸡的 ElasticSearch 源码解析 —— 启动流程（上）</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/08/05/es-code01/">渣渣菜鸡的 ElasticSearch 源码解析 —— 环境搭建</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/08/04/why-see-es-code/">渣渣菜鸡为什么要看 ElasticSearch 源码？</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/07/31/alipay02/">渣渣菜鸡的蚂蚁金服面试经历(二)</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/07/30/alipay01/">渣渣菜鸡的蚂蚁金服面试经历(一)</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/07/12/youzan/">渣渣菜鸡的有赞面试经历（一）</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/06/20/java-8-date/">20 个案例教你在 Java 8 中如何处理日期和时间?</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/06/19/SimpleDateFormat/">SimpleDateFormat 如何安全的使用？</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/05/26/paper/">苦逼的毕业论文经历</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/04/30/springboot_SpringApplication/">Spring Boot 2.0系列文章(七)：SpringApplication 深入探索</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/04/24/Distributed_lock/">分布式锁看这篇就够了</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/04/19/SpringBootApplication-annotation/">Spring Boot 2.0系列文章(六)：Spring Boot 2.0中SpringBootApplication注解详解</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/04/18/spring_boot2_project/">Spring Boot 2.0系列文章(五)：Spring Boot 2.0 项目源码结构预览</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/04/15/springboot2_code/">Spring Boot 2.0系列文章(四)：Spring Boot 2.0 源码阅读环境搭建</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/04/13/Spring_Boot_2.0_Configuration_Changelog/">Spring Boot 2.0系列文章(三)：Spring Boot 2.0 配置改变</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/03/27/blogs/">写这么多系列博客，怪不得找不到女朋友</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/03/06/SpringBoot2-new-features/">Spring Boot 2.0系列文章(二)：Spring Boot 2.0 新特性详解</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/03/06/SpringBoot2-Migration-Guide/">Spring Boot 2.0系列文章(一)：Spring Boot 2.0 迁移指南</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/03/04/springboot-vedio/">小马哥 《Java 微服务实践 - Spring Boot 系列》强烈推荐</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/03/04/springcloud-vedio/">小马哥 《Java 微服务实践 - Spring Cloud 系列》强烈推荐</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/02/28/Java-Memory-Model/">《深入理解 Java 内存模型》读书笔记</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/02/07/SpringBoot-RocketMQ/">Spring Boot系列文章（六）：SpringBoot RocketMQ 整合使用和监控</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/02/07/rocketmq-example/">RocketMQ系列文章（三）：RocketMQ 简单的消息示例</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/02/06/RocketMQ-install/">RocketMQ系列文章（二）：RocketMQ 安装及快速入门</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/02/05/RocketMQ/">RocketMQ系列文章（一）：RocketMQ 初探</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/28/RabbitMQ/">Spring Boot系列文章（五）：SpringBoot RabbitMQ 整合进阶版</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/27/SpringBoot-ActiveMQ/">Spring Boot系列文章（四）：SpringBoot ActiveMQ 整合使用</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/26/SpringBoot-RabbitMQ/">Spring Boot系列文章（三）：SpringBoot  RabbitMQ 整合使用</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/25/Docker-install/">Docker系列文章（二）：Mac 安装 Docker 及常用命令</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/24/mac/">MacBook Pro 初体验</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/17/SpringBoot-Admin/">Spring Boot系列文章（二）：SpringBoot Admin 使用指南</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/09/lombok/">Lombok 看这篇就够了</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/05/SpringBoot-Kafka/">Spring Boot系列文章（一）：SpringBoot Kafka 整合使用</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/04/Kafka/">Kafka 安装及快速入门</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/04/weixin/">为什么要重新运营以前的公众号呢？</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/12/27/consul-install/">Windows 下安装 Consul</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/12/25/ELK/">Elasticsearch 系列文章（五）：ELK 实时日志分析平台环境搭建</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/12/18/hexo-yilia/">Hexo + yilia 搭建博客可能会遇到的所有疑问</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/12/13/Google-Developer-Days/">谷歌开发者大会收获满满，不去真 “可惜” 了</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/12/09/CodeMirror/">使用 CodeMirror 打造属于自己的在线代码编辑器</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/12/08/netty-01-env/">Netty系列文章（一）：Netty 源码阅读之初始环境搭建</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/12/03/RestTemplate/">RestTemplate 详解</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/12/02/wx-01/">实习圈群里提问小记</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/11/26/Docker-harbor/">Docker系列文章（一）：基于 Harbor 搭建 Docker 私有镜像仓库</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/11/18/flow-control/">基于分布式环境下限流系统的设计</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/11/18/Money-management/">谈谈我的理财</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/11/11/recommended-books/">送你一份双十一剁手书单【墙裂推荐】</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/11/11/Maven-dependencies-dependencyManagement/">Maven 中 dependencies 与 dependencyManagement 的区别</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/10/28/Data-Desensitization/">小白谈数据脱敏</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/10/21/HBase-metrics/">HBase 集群监控</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/10/18/ElasticSearch-nodes-metrics/">Elasticsearch 系列文章（四）：ElasticSearch 单个节点监控</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/10/15/ElasticSearch-cluster-health-metrics/">Elasticsearch 系列文章（三）：ElasticSearch 集群监控</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/10/14/Nexus3-Maven/">Centos7 搭建最新 Nexus3 Maven 私服</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/10/14/JsonPath/">JsonPath —— JSON 解析神器</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/09/23/Guava-limit/">Google Guava 缓存实现接口的限流</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/09/17/Interview-summary/">面试过阿里等互联网大公司，我知道了这些套路</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/09/15/linux-lua-lfs-install/">Linux 下 lua 开发环境安装及安装 luafilesystem</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/09/09/Elasticsearch-install/">Elasticsearch 系列文章（二）：全文搜索引擎 Elasticsearch 集群搭建入门教程</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/09/08/Elasticsearch-analyzers/">Elasticsearch 系列文章（一）：Elasticsearch 默认分词器和中分分词器之间的比较及使用方法</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/08/28/recommend-books/">那些年我看过的书 —— 致敬我的大学生活 —— Say Good Bye ！</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/08/18/Ubuntu-install-Nginx/">Ubuntu16.10 安装 Nginx</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/08/11/most-success/">马云热血励志演讲《最伟大的成功》</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/08/08/android-projects/">源码大招：不服来战！撸这些完整项目，你不牛逼都难！</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/08/05/Nginx/">Nginx 基本知识快速入门</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/08/04/alibaba/">秋招第三站 —— 内推阿里（一面）</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/08/04/yaxin/">秋招第一站 —— 亚信科技</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/08/04/iqiyi/">秋招第二站 —— 内推爱奇艺（一面二面）</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/07/29/ThreadPool/">Java 线程池艺术探索</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/07/25/Java-performance-tuning/">Java 性能调优需要格外注意的细节</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/07/21/Spring-MVC03/">Spring MVC系列文章（五）：看透 Spring MVC 源代码分析与实践 ——  Spring MVC 组件分析</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/07/14/Spring-MVC01/">Spring MVC系列文章（三）：看透 Spring MVC 源代码分析与实践 ——  网站基础知识</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/07/14/Spring-MVC02/">Spring MVC系列文章（四）：看透 Spring MVC 源代码分析与实践 ——  俯视 Spring MVC</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/07/09/servlet/">通过源码详解 Servlet</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/28/Velocity-foreach/">Velocity 循环指令一种好的解决方法</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/23/java-io/">Java IO流学习超详细总结（图文并茂）</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/23/AJAX/">AJAX 学习</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/20/Java-error1/">java.sql.SQLException Field 'id' doesn't have a default value</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/19/中缀表达式转换成前缀和后缀表达式这类题目的超实用解题技巧/">中缀表达式转换成前缀和后缀表达式这类题目的超实用解题技巧</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/18/Bootstrap入门需掌握的知识点（二）/">Bootstrap入门需掌握的知识点（二）</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/18/Bootstrap入门需掌握的知识点（一）/">Bootstrap入门需掌握的知识点（一）</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/18/循环队列的相关条件和公式/">循环队列的相关条件和公式</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/17/详解 Filter 过滤器/">详解 Filter 过滤器</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/17/blog-talk/">搭建一个博客项目后的碎碎念</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/17/详细深入分析 Java ClassLoader 工作机制/">详细深入分析 Java ClassLoader 工作机制</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/16/通过项目逐步深入了解Spring MVC（一）/">通过项目逐步深入了解Spring MVC（一）</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/15/通过项目逐步深入了解Mybatis(四)/">通过项目逐步深入了解Mybatis（四）</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/14/通过项目逐步深入了解Mybatis(三)/">通过项目逐步深入了解Mybatis（三）</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/Hexo-yilia-toc/">Hexo + yilia 主题实现文章目录</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/HashMap-Hashtable/">HashMap、Hashtable、HashSet 和 ConcurrentHashMap 的比较</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/Spring MVC+Hibernate JPA搭建的博客系统项目中所遇到的坑/">Spring MVC系列文章（二）：Spring MVC+Hibernate JPA搭建的博客系统项目中所遇到的坑</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/Spring MVC + Hibernate JPA + Bootstrap 搭建的博客系统/">Spring MVC系列文章（一）：Spring MVC + Hibernate JPA + Bootstrap 搭建的博客系统 Demo</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/Java-Thread/">《Java 多线程编程核心技术》学习笔记及总结</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/Python爬虫实战之爬取糗事百科段子/">Python爬虫实战之爬取糗事百科段子</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/通过项目逐步深入了解Mybatis(二)/">通过项目逐步深入了解Mybatis（二）</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/Pyspider框架 —— Python爬虫实战之爬取 V2EX 网站帖子/">Pyspider框架 —— Python爬虫实战之爬取 V2EX 网站帖子</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/MySQL-select-good/">MySQL 处理海量数据时的一些优化查询速度方法</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/MyBatis-foreach/">MyBatis的foreach语句详解</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/Java连接Oracle数据库的三种连接方式/">Java连接Oracle数据库的三种连接方式</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/【字符串】判断两字符串是否互为旋转词？/">【字符串】判断两字符串是否互为旋转词？</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/【字符串】字符串逆序/">字符串</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/feiji/">记录下自己第一次坐飞机的感受</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/JVM性能调优监控工具jps、jstack、jmap、jhat、jstat等使用详解/">JVM性能调优监控工具jps、jstack、jmap、jhat、jstat等使用详解</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/Java-16-lession/">《疯狂 Java 突破程序员基本功的 16 课》读书笔记</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/奇怪的Java题：为什么128 == 128返回为False，而127 == 127会返回为True-/">奇怪的Java题：为什么128 == 128返回为False，而127 == 127会返回为True?</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/利用Github Page 搭建个人博客网站/">利用Github Page 搭建个人博客网站</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/深入分析 Java Web 中的中文编码问题/">深入分析 Java Web 中的中文编码问题</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/程序访问文件的几种方式/">程序访问文件的几种方式</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/深度探究Java 中 finally 语句块/">深度探究Java 中 finally 语句块</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/解决jdk1.8中发送邮件失败（handshake_failure）问题/">解决jdk1.8中发送邮件失败（handshake_failure）问题</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/java-var/">从对象深入分析 Java 中实例变量和类变量的区别</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/String-new/">关于String s = new String("xyz"); 创建几个对象的问题</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/java读取文件/">Java读取文件</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/Java NIO 系列教程/">Java NIO 系列教程</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/Python爬虫实战之爬取百度贴吧帖子/">Python爬虫实战之爬取百度贴吧帖子</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/12/通过项目逐步深入了解Mybatis(一)/">通过项目逐步深入了解Mybatis（一）</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/02/poetry2/"> 六月 —— 愿你做最美好的自己！</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/05/12/poetry/">最近很火的鸡汤，分享给大家</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/04/13/Hexo-yilia-changyan/">Github pages + Hexo 博客 yilia 主题使用畅言评论系统</a></li></ul>
    <script src="https://7.url.cn/edu/jslib/comb/require-2.1.6,jquery-1.9.1.min.js"></script>
    <script>
        $(".post-list").addClass("toc-article");
        $(".post-list-item a").attr("target","_blank");
        $("#post-nav-button > a:nth-child(2)").click(function() {
            $(".fa-bars, .fa-times").toggle();
            $(".post-list").toggle(300);
            if ($(".toc").length > 0) {
                $("#toc, #tocButton").toggle(200, function() {
                    if ($(".switch-area").is(":visible")) {
                        $("#tocButton").attr("value", valueHide);
                        }
                    })
            }
            else {
            }
        })
    </script>



    <script>
        
    </script>
</div>
      <footer id="footer">
    <div class="outer">
        <div id="footer-info">
            <div class="footer-left">
                &copy; 2019 zhisheng
            </div>
        </div>
        
            <div class="visit">
                
                    <span id="busuanzi_container_site_pv" style='display:none'>
                        <span id="site-visit" >本站总访问量: 
                            <span id="busuanzi_value_site_pv"></span>
                        </span>
                    </span>
                
                
                    <span>, </span>
                
                
                    <span id="busuanzi_container_page_pv" style='display:none'>
                        <span id="page-visit">本文总阅读量: 
                            <span id="busuanzi_value_page_pv"></span>
                        </span>
                    </span>
                
            </div>
        
    </div>
</footer>

    </div>
    <script src="https://7.url.cn/edu/jslib/comb/require-2.1.6,jquery-1.9.1.min.js"></script>
<script src="/js/main.js"></script>

    <script>
        $(document).ready(function() {
            var backgroundnum = 24;
            var backgroundimg = "url(/background/bg-x.jpg)".replace(/x/gi, Math.ceil(Math.random() * backgroundnum));
            $("#mobile-nav").css({"background-image": backgroundimg,"background-size": "cover","background-position": "center"});
            $(".left-col").css({"background-image": backgroundimg,"background-size": "cover","background-position": "center"});
        })
    </script>




	<script>
	var _hmt = _hmt || [];
	(function() {
	  var hm = document.createElement("script");
	  hm.src = "https://hm.baidu.com/hm.js?c41be5a0c9f014e977695f66c065b5d3";
	  var s = document.getElementsByTagName("script")[0]; 
	  s.parentNode.insertBefore(hm, s);
	})();
	</script>


<div class="scroll" id="scroll">
    <a href="#"><i class="fa fa-arrow-up"></i></a>
    <a href="#comments"><i class="fa fa-comments-o"></i></a>
    <a href="#footer"><i class="fa fa-arrow-down"></i></a>
</div>
<script>
    $(document).ready(function() {
        if ($("#comments").length < 1) {
            $("#scroll > a:nth-child(2)").hide();
        };
    })
</script>

<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js">
</script>

  <script language="javascript">
    $(function() {
        $("a[title]").each(function() {
            var a = $(this);
            var title = a.attr('title');
            if (title == undefined || title == "") return;
            a.data('title', title).removeAttr('title').hover(

            function() {
                var offset = a.offset();
                $("<div id=\"anchortitlecontainer\"></div>").appendTo($("body")).html(title).css({
                    top: offset.top - a.outerHeight() - 15,
                    left: offset.left + a.outerWidth()/2 + 1
                }).fadeIn(function() {
                    var pop = $(this);
                    setTimeout(function() {
                        pop.remove();
                    }, pop.text().length * 800);
                });
            }, function() {
                $("#anchortitlecontainer").remove();
            });
        });
    });
</script>


  </div>
</body>
</html>